class SuperTask {
  constructor(parallelCount = 2) {
    this.parallelCount = parallelCount
    this.runningCount = 0
    this.tasks = []
    this.over = undefined
  }

  add(task) {
    return new Promise((resolve, reject) => {
      this.tasks.push({task, resolve, reject})
      this._run()
    })
  }

  _run() {
    if (this.tasks.length == 0 && this.runningCount == 0) {
      return this.over && this.over()
    }
    while (this.runningCount < this.parallelCount && this.tasks.length) {
      const { task, resolve, reject } = this.tasks.shift()
      this.runningCount++
      task().then(resolve, reject).finally(() => {
        this.runningCount--
        this._run()
      })
    }
  }

  waitOver() {
    if (this.tasks.length == 0 && this.runningCount == 0) return;
    return new Promise((resolve, reject) => {
      this.over = () => {
        resolve()
        this.over = undefined
      }
    })
  }
}

export default SuperTask

const superTask = new SuperTask()

function addTask(time, name) {
  superTask.add(() => { return new Promise(
    (resolve, reject) => {
      setTimeout(() => {
        console.log(`task:${name}完成`)
        resolve()
      }, time)
    })}
  )
}

async function rrr() {
  addTask(1000, 1)
  addTask(1000, 2)
  addTask(1000, 3)
  addTask(1000, 4)
  addTask(1000, 5)
  
  await superTask.waitOver()
  
  console.log(123456)
}